package com.touch.core;

import java.io.*;
import java.net.*;
/**
 * The abstract UDP class. Basically a UDPServer and UDPClient does not vary much so this contains all of the shared functionality of both.
 * @author Homicidal Monkey
 * @version 10.1.13
 * @since r463
 * @see com/touch/Licence
 */
public abstract class AbstractUDPObject extends AbstractNetObject
{	
	protected DatagramSocket socket;
	/**
	 * Creates a new AbstractUDPObject with the input of a new DatagramSocket. This cannot be initiated directly.
	 * @since r463
	 */
	protected AbstractUDPObject(final DatagramSocket socket)
	{
		//set the socket
		this.socket = socket;
	}		
	public void run()
	{
		//only run while this is still alive
		while(this.isAlive)
		{
			try 
			{
				//create a new buffer
				final byte buffer[] = new byte[BUFFERSIZE];
				//create a new packet
				final DatagramPacket packet = new DatagramPacket(buffer, buffer.length);		
			
				//listen for a packet
				this.socket.receive(packet);
				//invoke the event handler
				this.invokeNetListener(
					new InetSocketAddress(packet.getAddress(), packet.getPort()), trim(packet.getData()));
			} 
			catch(final IOException e) 
			{			
				//an error occurred with the UDPSocket.
				e.printStackTrace();
			}
		}
	}
	/**
	 * Closes the specified socket. This will  attempt to end all processes without errors.
	 * @since r463
	 */
	public void close()
	{
		try 
		{
			//stop the thread
			this.isAlive = false;
			//close the socket
			this.socket.close();
		}
		catch(final Exception e)
		{
			//in case of an error, just print it.
			e.printStackTrace();
		}
	}
	/**
	 * Trims a message and removes unnecessary bytes.
	 * @param byteblock Message to trim.
	 * @return The trimmed message
	 * @since r463
	 */
	public byte[] trim(final byte[] byteblock)
	{
		//make a new block to copy to
		final byte[] newblock;
		//the end of the specified message
		int end = 0;
		//scan for the end character
		for(int i = 0; i < byteblock.length; i++)
			if(byteblock[i] == NetConstants.END_CHAR)
				end = i + 1;
		//create the new byte block
		newblock = new byte[end];
		//copy the old message to the new byte block
		for(int i = 0; i < end; i ++)
			newblock[i] = byteblock[i];
		//return the new byte block
		return newblock;		
	}
}
